home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Internet
/
Collection of Internet.iso
/
infosrvr
/
dev
/
scott
/
WWW
/
NextStep
/
Implementation
/
StyleToy.m
< prev
next >
Wrap
Text File
|
1993-07-06
|
9KB
|
367 lines
/* Style Toy: Allows user manipulation of styles StyleToy.m
** --------- ----------------------------------
*/
#import "StyleToy.h"
#import "HTParse.h"
#import "HTStyle.h"
#import "HTUtils.h"
#import "HyperText.h"
#define THIS_TEXT (HyperText *)[[[NXApp mainWindow] contentView] docView]
/* Field numbers in the parameter form:
*/
#define SGMLTAG_FIELD 4
#define FONT_NAME_FIELD 2
#define FONT_SIZE_FIELD 3
#define FIRST_INDENT_FIELD 0
#define SECOND_INDENT_FIELD 1
@implementation StyleToy
extern char * appDirectory; /* Pointer to directory for application */
// Global styleSheet available to every one:
HTStyleSheet * styleSheet = 0;
static HTStyle * style; /* Current Style */
static OpenPanel * open_panel; /* Keep the open panel alive */
static SavePanel * save_panel; /* Keep a Save panel too */
// Create new one:
+ new
{
self = [super new];
[self loadDefaultStyleSheet];
return self;
}
// Set connections to other objects:
- setTabForm:anObject
{
TabForm = anObject;
return self;
}
- setParameterForm:anObject
{
ParameterForm = anObject;
return self;
}
- setStylePanel:anObject
{
StylePanel = anObject;
return self;
}
- setNameForm:anObject
{
NameForm = anObject;
return self;
}
// ACTION METHODS
// ==============
// Display style in the panel
- display_style
{
if(style->name) [NameForm setStringValue:style->name at:0];
else [NameForm setStringValue:"" at:0];
if(style->SGMLTag) [ParameterForm setStringValue:style->SGMLTag at:SGMLTAG_FIELD];
else [ParameterForm setStringValue:"" at:SGMLTAG_FIELD];
[ParameterForm setStringValue:[style->font name] at:FONT_NAME_FIELD];
[ParameterForm setFloatValue:style->fontSize at:FONT_SIZE_FIELD];
if(style->paragraph) {
char tabstring[255];
int i;
[ParameterForm setFloatValue:style->paragraph->indent1st
at:FIRST_INDENT_FIELD];
[ParameterForm setFloatValue:style->paragraph->indent2nd
at:SECOND_INDENT_FIELD];
tabstring[0]=0;
for(i=0; i < style->paragraph->numTabs; i++) {
sprintf(tabstring+strlen(tabstring), "%.0f ", style->paragraph->tabs[i].x);
}
[TabForm setStringValue:tabstring at:0];
}
return self;
}
// Load style from Panel
//
// @@ Tabs not loaded
-load_style
{
char * name = 0;
char * stripped;
style->fontSize=[ParameterForm floatValueAt:FONT_SIZE_FIELD];
StrAllocCopy(name, [NameForm stringValueAt:0]);
stripped = HTStrip(name);
if (*stripped) {
id font;
font = [Font newFont:stripped size:style->fontSize];
if (font) style->font = font;
}
free(name);
name = 0;
StrAllocCopy(name, [ParameterForm stringValueAt:SGMLTAG_FIELD]);
stripped = HTStrip(name);
if (*stripped) {
StrAllocCopy(style->SGMLTag, stripped);
}
free(name);
name = 0;
if (!style->paragraph) style->paragraph = malloc(sizeof(*(style->paragraph)));
style->paragraph->indent1st = [ParameterForm floatValueAt: FIRST_INDENT_FIELD];
style->paragraph->indent2nd = [ParameterForm floatValueAt: SECOND_INDENT_FIELD];
return self;
}
// Open a style sheet from a file
// ------------------------------
//
// We overlay any previously defined styles with new ones, but leave
// old ones which are not redefined.
- open:sender
{
NXStream * s; // The file stream
const char * filename; // The name of the file
char *typelist[2] = {"style",(char *)0}; // Extension must be ".style."
if (!open_panel) {
open_panel = [OpenPanel new];
[open_panel allowMultipleFiles:NO];
}
if (![open_panel runModalForTypes:typelist]) {
if (TRACE) printf("No file selected.\n");
return nil;
}
filename = [open_panel filename];
s = NXMapFile(filename, NX_READONLY);
if (!s) {
if(TRACE) printf("Styles: Can't open file %s\n", filename);
return nil;
}
if (!styleSheet) styleSheet = HTStyleSheetNew();
StrAllocCopy(styleSheet->name, filename);
if (TRACE) printf("Stylesheet: New one called %s.\n", styleSheet->name);
(void)HTStyleSheetRead(styleSheet, s);
NXCloseMemory(s, NX_FREEBUFFER);
style = styleSheet->styles;
[self display_style];
return self;
}
// Load default style sheet
// ------------------------
//
// We load EITHER the user's style sheet (if it exists) OR the system one.
// This saves a bit of time on load. An alternative would be to load the
// system style sheet and then overload the styles in the user's, so that
// he could redefine a subset only of the styles.
// If the HOME directory is defined, then it is always used a the
// style sheet name, so that any changes will be saved in the user's
// $(HOME)/WWW directory.
- loadDefaultStyleSheet
{
NXStream * stream;
if (!styleSheet) styleSheet = HTStyleSheetNew();
styleSheet->name = malloc(strlen(appDirectory)+13+1);
strcpy(styleSheet->name, appDirectory);
strcat(styleSheet->name, "default.style");
if (getenv("HOME")) {
char name[256];
strcpy(name, getenv("HOME"));
strcat(name, "/WWW/default.style");
StrAllocCopy(styleSheet->name, name);
stream = NXMapFile(name, NX_READONLY);
} else stream = 0;
if (!stream) {
char name[256];
strcpy(name, appDirectory);
strcat(name, "default.style");
if (TRACE) printf("Couldn't open $(HOME)/WWW/default.style\n");
stream = NXMapFile(name, NX_READONLY);
if (!stream)
printf("Couldn't open %s, errno=%i\n", name, errno);
}
if (stream) {
(void)HTStyleSheetRead(styleSheet, stream);
NXCloseMemory(stream, NX_FREEBUFFER);
style = styleSheet->styles;
[self display_style];
}
return self;
}
// Save style sheet to a file
// --------------------------
- saveAs:sender
{
NXStream * s; // The file stream
char * slash;
int status;
char * suggestion=0; // The name of the file to suggest
const char * filename; // The name chosen
if (!save_panel) {
save_panel = [SavePanel new]; // Keep between invocations
}
StrAllocCopy(suggestion,styleSheet->name);
slash = rindex(suggestion, '/'); // Point to last slash
if (slash) {
*slash++ = 0; /* Separate directory and filename */
status = [save_panel runModalForDirectory:suggestion file:slash];
} else {
status = [save_panel runModalForDirectory:"." file:suggestion];
}
free(suggestion);
if (!status) {
if (TRACE) printf("No file selected.\n");
return nil;
}
filename = [save_panel filename];
s = NXMapFile(filename, NX_WRITEONLY);
if (!s) {
if(TRACE) printf("Styles: Can't open file %s for write\n", filename);
return nil;
}
StrAllocCopy(styleSheet->name, filename);
if (TRACE) printf("StylestyleSheet: Saving as `%s'.\n", styleSheet->name);
(void)HTStyleSheetWrite(styleSheet, s);
NXSaveToFile(s, styleSheet->name);
NXCloseMemory(s, NX_FREEBUFFER);
style = styleSheet->styles;
[self display_style];
return self;
}
// Move to next style
// ------------------
- NextButton:sender
{
if (styleSheet->styles)
if (styleSheet->styles->next)
if (style->next) {
style = style->next;
} else {
style = styleSheet->styles;
}
[self display_style];
return self;
}
- FindUnstyledButton:sender
{
[THIS_TEXT selectUnstyled: styleSheet];
return self;
}
// Apply current style to selection
// --------------------------------
- ApplyButton:sender
{
[THIS_TEXT applyStyle:style];
return self;
}
- applyStyleNamed: (const char *)name
{
HTStyle * thisStyle = HTStyleNamed(styleSheet, name);
if (!thisStyle) return nil;
return [THIS_TEXT applyStyle:thisStyle];
}
- heading1Button:sender { return [self applyStyleNamed:"Heading1" ]; }
- heading2Button:sender { return [self applyStyleNamed:"Heading2" ]; }
- heading3Button:sender { return [self applyStyleNamed:"Heading3" ]; }
- heading4Button:sender { return [self applyStyleNamed:"Heading4" ]; }
- heading5Button:sender { return [self applyStyleNamed:"Heading5" ]; }
- heading6Button:sender { return [self applyStyleNamed:"Heading6" ]; }
- normalButton:sender { return [self applyStyleNamed:"Normal" ]; }
- addressButton:sender { return [self applyStyleNamed:"Address" ]; }
- exampleButton:sender { return [self applyStyleNamed:"Example" ]; }
- listButton:sender { return [self applyStyleNamed:"List" ]; }
- menuButton:sender { return [self applyStyleNamed:"Menu" ]; }
- dirButton:sender { return [self applyStyleNamed:"Dir" ]; }
- glossaryButton:sender { return [self applyStyleNamed:"Glossary" ]; }
// Move to previous style
// ----------------------
- PreviousButton:sender
{
HTStyle * scan;
for (scan = styleSheet->styles; scan; scan=scan->next) {
if ((scan->next==style) || (scan->next==0)){
style = scan;
break;
}
}
[self display_style];
return self;
}
- SetButton:sender
{
[self load_style];
[THIS_TEXT updateStyle:style];
return self;
}
- PickButton:sender
{
HTStyle * st = [THIS_TEXT selectionStyle:styleSheet];
if (st) {
style = st;
[self display_style];
}
return self;
}
- ApplyToSimilar:sender
{
return [THIS_TEXT applyToSimilar:style];
}
@end